package com.wanyang.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.wanyang.aliyun.dto.TextTaskDTO;
import com.wanyang.aliyun.service.AliyunContentScanService;
import com.wanyang.bo.MemberBO;
import com.wanyang.constant.BusinessTypeConstant;
import com.wanyang.dao.CommonDao;
import com.wanyang.dao.PostCommentDao;
import com.wanyang.dao.PostDao;
import com.wanyang.dos.IllegalContentDO;
import com.wanyang.dos.PostCommentDO;
import com.wanyang.dos.PostCommentDOExample;
import com.wanyang.dto.PageDTO;
import com.wanyang.dto.PrincipalCommentDTO;
import com.wanyang.dto.SubCommentDTO;
import com.wanyang.mapper.IllegalContentDOMapper;
import com.wanyang.mapper.PostCommentDOMapper;
import com.wanyang.utils.DateUtil;
import com.wanyang.vo.PostCommentVO;
import com.wanyang.vo.PrincipalCommentVO;
import com.wanyang.vo.SubCommentVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PostCommentServiceImpl implements PostCommentService {
    @Resource
    private PostCommentDOMapper postCommentDOMapper;

    @Resource
    private PostDao postDao;

    @Resource
    private PostCommentDao postCommentDao;

    @Resource
    private CommonDao commonDao;

    @Autowired
    private MemberLikeService memberLikeService;

    @Autowired
    private AliyunContentScanService aliyunContentScanService;

    @Resource
    private IllegalContentDOMapper illegalContentDOMapper;

    @Override
    public List<PostCommentVO> queryDefaultComment(Integer postId) {
        List<PostCommentVO> postCommentVOS = postDao.queryDefaultComment(postId);

        MemberBO memberBO = UserContext.get();
        if (memberBO != null && CollectionUtil.isNotEmpty(postCommentVOS)) {
            List<Integer> targetIds = postCommentVOS.stream().map(PostCommentVO::getId).collect(Collectors.toList());

            List<Integer> likedIds = memberLikeService.queryLikes(memberBO.getId(), MemberLikeService.like_type_post_comment, targetIds);

            for (PostCommentVO postCommentVO : postCommentVOS) {
                if (likedIds.contains(postCommentVO.getId())) {
                    postCommentVO.setLike(true);
                }
            }
        }

        return postCommentVOS;
    }

    private List<PostCommentVO> queryPrincipalComment(Integer postId) {
        return postDao.queryPrincipalComment(postId);
    }

    @Override
    public List<PrincipalCommentVO> queryPrincipalCommentPage(Integer postId, PageDTO pageDTO) {
        PageHelper.startPage(pageDTO);
        List<PostCommentVO> comments = queryPrincipalComment(postId);

        List<PrincipalCommentVO> principalComments = new ArrayList<>();

        if (!CollectionUtils.isEmpty(comments)) {
            // 查询出这些评论的子评论
            List<Integer> commentIds = comments.stream().map(PostCommentDO::getId).collect(Collectors.toList());
            int limit = 4;
            List<SubCommentVO> subComments = this.querySubCommentPageByGroup(commentIds, limit);

            Map<Integer, List<SubCommentVO>> subCommentGroupBy = subComments.stream().collect(Collectors.groupingBy(SubCommentVO::getParentId));

            comments.forEach(postCommentVO -> {
                PrincipalCommentVO principalCommentVO = new PrincipalCommentVO();
                principalCommentVO.setId(postCommentVO.getId());
                principalCommentVO.setCommentMemberId(postCommentVO.getCommentMemberId());
                principalCommentVO.setCommenterNickname(postCommentVO.getCommenterNickname());
                principalCommentVO.setCommenterAvatar(postCommentVO.getCommenterAvatar());
                principalCommentVO.setComment(postCommentVO.getContent());
                principalCommentVO.setCreateTime(postCommentVO.getCreateTime());
                principalCommentVO.setCreateTimeStr(DateUtil.handleTime(postCommentVO.getCreateTime()));
                principalCommentVO.setLikes(postCommentVO.getLikes());
                principalCommentVO.setSubTotal(postCommentVO.getSubCommentQuantity());

                List<SubCommentVO> sub = subCommentGroupBy.get(postCommentVO.getId());
                if (sub == null)
                    sub = new ArrayList<>();

                if (sub.size() > limit) {
                    sub = sub.subList(0, limit-1);
                }

                principalCommentVO.setSubComments(sub);

                principalComments.add(principalCommentVO);
            });

        }

        // 遍历所有的评论，处理点赞信息
        List<Integer> commentIds = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(principalComments)) {
            for (PrincipalCommentVO principalComment : principalComments) {
                commentIds.add(principalComment.getId());
                List<SubCommentVO> subComments = principalComment.getSubComments();
                if (CollectionUtil.isNotEmpty(subComments)) {
                    for (SubCommentVO subComment : subComments) {
                        commentIds.add(subComment.getId());
                    }
                }
            }
        }

        MemberBO memberBO = UserContext.get();
        if (CollectionUtil.isNotEmpty(commentIds) && memberBO != null) {
            List<Integer> likedIds = memberLikeService.queryLikes(memberBO.getId(), MemberLikeService.like_type_post_comment, commentIds);

            for (PrincipalCommentVO principalComment : principalComments) {
                if (likedIds.contains(principalComment.getId()))
                    principalComment.setLike(true);

                List<SubCommentVO> subComments = principalComment.getSubComments();
                if (CollectionUtil.isNotEmpty(subComments)) {
                    for (SubCommentVO subComment : subComments) {
                        if (likedIds.contains(subComment.getId()))
                            subComment.setLike(true);
                    }
                }
            }
        }

        return principalComments;
    }


    @Override
    public List<SubCommentVO> querySubCommentPage(Integer postCommentId, PageDTO pageDTO) {
        PageHelper.startPage(pageDTO);
        List<SubCommentVO> subCommentVOs = postCommentDao.querySubComment(postCommentId);

        MemberBO memberBO = UserContext.get();

        if (memberBO != null && CollectionUtil.isNotEmpty(subCommentVOs)) {
            List<Integer> commentIds = subCommentVOs.stream().map(SubCommentVO::getId).collect(Collectors.toList());
            List<Integer> likedIds = memberLikeService.queryLikes(memberBO.getId(), MemberLikeService.like_type_post_comment
                    , commentIds);

            for (SubCommentVO subCommentVO : subCommentVOs) {
                if (likedIds.contains(subCommentVO.getId())) {
                    subCommentVO.setLike(true);
                }
            }

        }

        return subCommentVOs;
    }

    @Override
    public List<SubCommentVO> querySubCommentPageByGroup(List<Integer> postCommentIds, Integer limit) {
        return postCommentDao.querySubCommentPageByGroup(postCommentIds, limit);
    }

    @Override
    @Transactional
    public Integer writePrincipalComment(PrincipalCommentDTO principalCommentDTO) {
        MemberBO memberBO = UserContext.get();
        Integer memberId = memberBO.getId();

        PostCommentDO postCommentDO = new PostCommentDO();
        postCommentDO.setPostId(principalCommentDTO.getPostId());
        postCommentDO.setCommentMemberId(memberId);
        postCommentDO.setContent(principalCommentDTO.getContent());
        postCommentDO.setCreateTime(DateUtil.currentUnixTime());
        postCommentDO.setIsDelete(false);
        postCommentDO.setLikes(0);
        postCommentDO.setParentId(0);
        postCommentDO.setSubCommentQuantity(0);
        postCommentDOMapper.insertSelective(postCommentDO);
        Integer id = commonDao.mysqlLastId();

        postDao.updateComments(principalCommentDTO.getPostId(), 1);

        // 文本审核
        TextTaskDTO textTaskDTO = new TextTaskDTO(UUID.randomUUID().toString(), postCommentDO.getContent());

        aliyunContentScanService.syncTextScan(Collections.singletonList(textTaskDTO), (dataId, pass) -> {
            if (!pass) {
                PostCommentDO update = new PostCommentDO();
                update.setId(id);
                update.setIsDelete(true);
                postCommentDOMapper.updateByPrimaryKeySelective(update);

                // 记录违规数据
                IllegalContentDO illegalContentDO = new IllegalContentDO();
                illegalContentDO.setBusinessId(id);
                illegalContentDO.setBusinessType(BusinessTypeConstant.POST_COMMENT);
                illegalContentDO.setMemeberId(UserContext.get().getId());
                illegalContentDO.setCreateTime(DateUtil.currentUnixTime());
                illegalContentDO.setAliyunResponse(null);
                illegalContentDO.setContent(JSONUtil.toJsonStr(textTaskDTO));
                illegalContentDOMapper.insertSelective(illegalContentDO);
            }
        });

        return id;
    }

    @Override
    @Transactional
    public Integer writeSubComment(SubCommentDTO subCommentDTO) {
        MemberBO memberBO = UserContext.get();
        Integer memberId = memberBO.getId();

        PostCommentDO postCommentDO = new PostCommentDO();
        postCommentDO.setPostId(subCommentDTO.getPostId());
        postCommentDO.setReplyId(subCommentDTO.getReplyId());
        postCommentDO.setCommentMemberId(memberId);
        postCommentDO.setContent(subCommentDTO.getContent());
        postCommentDO.setCreateTime(DateUtil.currentUnixTime());
        postCommentDO.setIsDelete(false);
        postCommentDO.setLikes(0);
        postCommentDO.setParentId(subCommentDTO.getParentCommentId());

        postCommentDOMapper.insertSelective(postCommentDO);

        Integer id = commonDao.mysqlLastId();

        // 更新父级评论数量
        postCommentDao.updateSubCommentCount(subCommentDTO.getParentCommentId(), 1);

        postDao.updateComments(subCommentDTO.getPostId(), 1);

        // 文本审核
        TextTaskDTO textTaskDTO = new TextTaskDTO(UUID.randomUUID().toString(), postCommentDO.getContent());

        aliyunContentScanService.syncTextScan(Collections.singletonList(textTaskDTO), (dataId, pass) -> {
            if (!pass) {
                PostCommentDO update = new PostCommentDO();
                update.setId(id);
                update.setIsDelete(true);
                postCommentDOMapper.updateByPrimaryKeySelective(update);

                // 记录违规数据
                IllegalContentDO illegalContentDO = new IllegalContentDO();
                illegalContentDO.setBusinessId(id);
                illegalContentDO.setBusinessType(BusinessTypeConstant.POST_COMMENT);
                illegalContentDO.setMemeberId(UserContext.get().getId());
                illegalContentDO.setCreateTime(DateUtil.currentUnixTime());
                illegalContentDO.setAliyunResponse(null);
                illegalContentDO.setContent(JSONUtil.toJsonStr(textTaskDTO));
                illegalContentDOMapper.insertSelective(illegalContentDO);
            }
        });

        return id;
    }

    @Override
    public void deleteComment(Integer postCommentId) {
        PostCommentDO postCommentDO = postCommentDOMapper.selectByPrimaryKey(postCommentId);

        if (postCommentDO != null) {
            if (postCommentDO.getParentId() == 0) {
                // 1级评论
                PostCommentDOExample example = new PostCommentDOExample();
                example.createCriteria()
                        .andParentIdEqualTo(postCommentId)
                        .andIsDeleteEqualTo(false);

                Long count = postCommentDOMapper.countByExample(example);
                postDao.updateComments(postCommentDO.getPostId(), -count.intValue());

            } else {
                postCommentDao.updateSubCommentCount(postCommentId, -1);
                postDao.updateComments(postCommentDO.getPostId(), -1);

            }

            PostCommentDO update = new PostCommentDO();
            update.setId(postCommentId);
            update.setIsDelete(true);
            postCommentDOMapper.updateByPrimaryKeySelective(update);
        }



    }
}
